package server.core;

import server.*;
import server.valves.ValveBase;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
Context容器的基础阀,保护META-INF和WEB-INF目录下的内容不被直接访问,
根据请求查找对应的wrapper并调用其invoke方法(未找到返回404,查找过程出错返回400)
*/
/*
2023/3/2 该类内容全部写完,后续直接使用,无需修改
by cyl
 */
final class StandardContextValve extends ValveBase {
    private static final String info = "server.core.StandardContextValve/1.0";
    //实现valve接口------------------------------------------------------------
    @Override
    public String getInfo() {
        return info;
    }

    @Override
    public void invoke(Request request, Response response, ValveContext valveContext) throws IOException, ServletException {
        //要求必须实现HttpServletRequest和HttpServletResponse接口
        if (!(request.getRequest() instanceof HttpServletRequest) ||
            !(response.getResponse() instanceof HttpServletResponse)) {
            return;
        }
        HttpServletRequest hreq = (HttpServletRequest)(request.getRequest());
        HttpServletResponse hres = (HttpServletResponse)(response.getResponse());
        String contextPath = hreq.getContextPath();
        String uri = ((HttpRequest)request).getDecodedRequestURI();
        //去掉应用名后的路径
        String path = uri.substring(contextPath.length()).toUpperCase();
        //META-INF和WEB-INF目录下的内容是受保护的,不能直接访问,返回404
        if ("/META-INF".equals(path) ||
            "/WEB-INF".equals(path) ||
            path.startsWith("/META-INF/") ||
            path.startsWith("/WEB-INF/")) {
            notFound(uri, hres);
            return;
        }

        Context context = (Context)getContainer();
        Wrapper wrapper = null;
        try {
            wrapper = (Wrapper) context.map(request, true);
        } catch (IllegalArgumentException e) {
            //查找wrapper出错,返回400
            badRequest(uri, hres);
            return;
        }
        //未找到wrapper,返回404
        if (wrapper == null) {
            notFound(uri, hres);
            return;
        }

        request.setContext(context);
        response.setContext(context);
        //执行wrapper的invoke方法
        wrapper.invoke(request, response);
    }

    //设置响应状态码为404,响应描述为uri
    private void notFound(String uri, HttpServletResponse response) {
        try {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, uri);
        } catch (IOException e) {

        }
    }

    //设置响应状态码为400,响应描述为uri
    private void badRequest(String uri, HttpServletResponse response) {
        try {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, uri);
        } catch (IOException e) {

        }

    }
}
